package top.btcmarket;

import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class Encryption {

	private static final String password = "Hello";
	private static final String keyAlgorithm = "AES";
	private static final String encryptAlgorithm = "AES/CBC/PKCS5Padding";
	private static final String secretKeyFactoryAlgorithm = "PBKDF2WithHmacSHA1";

	public static String encrypt(String word) throws Exception {
		byte[] ivBytes;
		// String password="Hello";
		/*
		 * you can give whatever you want for password. This is for testing
		 * purpose
		 */
		SecureRandom random = new SecureRandom();
		byte bytes[] = new byte[20];
		random.nextBytes(bytes);
		byte[] saltBytes = bytes;
		// Derive the key
		SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKeyFactoryAlgorithm);
		PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
		SecretKey secretKey = factory.generateSecret(spec);
		SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), keyAlgorithm);
		// encrypting the word
		Cipher cipher = Cipher.getInstance(encryptAlgorithm);
		cipher.init(Cipher.ENCRYPT_MODE, secret);
		AlgorithmParameters params = cipher.getParameters();
		ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
		byte[] encryptedTextBytes = cipher.doFinal(word.getBytes("UTF-8"));
		// prepend salt and vi
		byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];
		System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);
		System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);
		System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);
		return new Base64().encodeToString(buffer);
	}

	public static String decrypt(String encryptedText) throws Exception {
		// String password="Hello";
		Cipher cipher = Cipher.getInstance(encryptAlgorithm);
		// strip off the salt and iv
		ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));
		byte[] saltBytes = new byte[20];
		buffer.get(saltBytes, 0, saltBytes.length);
		byte[] ivBytes1 = new byte[cipher.getBlockSize()];
		buffer.get(ivBytes1, 0, ivBytes1.length);
		byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes1.length];

		buffer.get(encryptedTextBytes);
		// Deriving the key
		SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKeyFactoryAlgorithm);
		PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
		SecretKey secretKey = factory.generateSecret(spec);
		SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), keyAlgorithm);
		cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
		byte[] decryptedTextBytes = null;
		try {
			decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}

		return new String(decryptedTextBytes);
	}

	public static void main(String[] args) throws Exception {
		// Encryption en=new Encryption();
		
//		  String encryptedWord=Encryption.encrypt("Testfsdfsdfsrsdfwerwerewr34sdfsdfsdfsdfsdyrty456dgert5443534fsdfsdfsdfsdf23423423");
//		  String encryptedWord=Encryption.encrypt("Test");
		  String encryptedWord="";
		  System.out.println("Encrypted word is : " + encryptedWord);
		  int length = encryptedWord.length();
		  int mod = length/3 ;
		  
		  System.out.println("length:"+length+", mod is : "+mod);
		  int s1 = mod ;
		  int s2 = mod*2 ;
		  
		  System.out.println("s1:"+s1+", s2 is : "+s2);
		  
		  String str1 = encryptedWord.substring(0,mod);
		  String str2 = encryptedWord.substring(mod,s2);
		  String str3 = encryptedWord.substring(s2,length);
		  
		  System.out.println("str1:"+str1);
		  System.out.println("str2:"+str2);
		  System.out.println("str3:"+str3);
		  
		  System.out.println(encryptedWord.equals(str1+str2+str3));
		  
		  System.out.println(encrypt(""));
		 

//		String encryptedWord = "jQ+rstGwLfDDcYskZ6CK0DSxibGUgYoxJrRIMQnASgHYOjKWz6iQW/8U4fVLbPYChMx4y+Hm4nxSSjz2gfQCYuJSbOFBlLWtOigFt8LPh/FSIAr8MGhBLtphSd8j6Y0eFl0ui0wbk0oN3zSiNXQPoMY3ByhDHjB60TLpZW5dp+DJfzII";
//		System.out.println("Decrypted word is : " + Encryption.decrypt(encryptedWord));
	}
}
